
// import oimo.collision.geometry.RayCastHit;
// import oimo.common.Vec3;
// import oimo.dynamics.rigidbody.Shape;

import { RayCastCallback } from "./RayCastCallback";
import { Shape } from "../rigidbody/Shape";
import { Vec3 } from "../../common/Vec3";
import { RayCastHit } from "../../collision/geometry/RayCastHit";

/**
 * A ray cast callback implementation that keeps only the closest hit data.
 * This is reusable, but make sure to clear the old result by calling
 * `RayCastClosest.clear` if used once or more before.
 */
export class RayCastClosest extends RayCastCallback {
	/**
	 * The shape the ray hit.
	 */
	shape: Shape;

	/**
	 * The position the ray hit at.
	 */
	position: Vec3;

	/**
	 * The normal vector of the surface the ray hit.
	 */
	normal: Vec3;

	/**
	 * The ratio of the position the ray hit from the start point to the end point.
	 */
	fraction: number;

	/**
	 * Whether the ray hit any shape in the world.
	 */
	hit: boolean;

	/**
	 * Default constructor.
	 */
	constructor() {
		super();
		this.position = new Vec3();
		this.normal = new Vec3();
		this.clear();
	}

	/**
	 * Clears the result data.
	 */
	public clear(): void {
		this.shape = null;
		this.fraction = 1;
		this.position.zero();
		this.normal.zero();
		this.hit = false;
	}

	public process(shape: Shape, hit: RayCastHit): void {
		if (hit.fraction < this.fraction) {
			this.shape = shape;
			this.hit = true;
			this.fraction = hit.fraction;
			this.position.copyFrom(hit.position);
			this.normal.copyFrom(hit.normal);
		}
	}

}
